package com.bitcoin.scheduler.service;

import com.bitcoin.scheduler.domain.Parameter;
import com.bitcoin.scheduler.repository.ParameterDao;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import lombok.Getter;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.query.NativeQuery;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Map;

/**
 * 监控数据库表 某字段是否有数据达到监控阙值
 */
@Service
public class TableMonitorService {
    @Autowired
    private ParameterDao parameterDao;
    @Autowired
    private ObjectMapper jsonMapper;
    @Autowired
    private MailService mailService;
    @Autowired
    @Getter
    private EntityManager entityManager;

    public void notice(String table, int maxDelayMinutes, int delayMinutes, Map config) {
        String emailList = MapUtils.getString(config, "email");
        String title = "[" + table + "]" + MapUtils.getString(config, "title");
        Map<String, Object> parameter = Maps.newConcurrentMap();
        parameter.put("title", title);
        parameter.put("table", table);
        parameter.put("maxDelayMinutes", maxDelayMinutes);
        parameter.put("delayMinutes", delayMinutes);

        for (String email : StringUtils.split(emailList, ";")) {
            mailService.tableMonitorEmail(title, email, parameter);
        }
    }

    public void monitor() throws ServiceException, IOException {
        Parameter parameter = parameterDao.findByParameterKey("TABLE_MONITOR").orElseThrow(() -> new ServiceException("未配置"));
        Map configList = jsonMapper.readValue(parameter.getParameterValue(), Map.class);
        for (Object table : configList.keySet()) {
            Map config = (Map) configList.get(table);
            int maxDelayMinutes = MapUtils.getInteger(config, "maxDelayMinutes");
            int delayMinutes = validate(table.toString(), MapUtils.getString(config, "column"));
            if (maxDelayMinutes < delayMinutes) {
                Map emailConfig = MapUtils.getMap(config, "notice");
                notice(table.toString(), maxDelayMinutes, delayMinutes, emailConfig);
            }
        }
    }


    public int validate(String tableName, String monitorColumn) {
        String sql = MessageFormat.format("SELECT TIMESTAMPDIFF(MINUTE ,{1},sysdate()) diffMinutes FROM {0} order by {1} desc limit 1",
            tableName, monitorColumn);
        Query query = getEntityManager().createNativeQuery(sql);
        query.unwrap(NativeQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        Map result = (Map) query.getSingleResult();
        return MapUtils.getInteger(result, "diffMinutes");
    }
}
